using TerritoryGame.Domain.ValueObjects;

namespace TerritoryGame.Domain.Services;

public interface IAreaCalculationService
{
    int CalculatePlayerArea(PlayerColor color, Dictionary<Position, PlayerColor> pixels);
    Dictionary<PlayerColor, int> CalculateAllAreas(Dictionary<Position, PlayerColor> pixels);
    int CalculateAreaChange(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels);
    void UpdateAreaCache(PlayerColor color, int areaChange);
    Dictionary<PlayerColor, int> GetCachedAreas();
    void ClearCache();
}

public class AreaCalculationService : IAreaCalculationService
{
    private readonly Dictionary<PlayerColor, int> _areaCache = new();
    private readonly object _cacheLock = new();

    public int CalculatePlayerArea(PlayerColor color, Dictionary<Position, PlayerColor> pixels)
    {
        return pixels.Values.Count(c => c == color);
    }

    public Dictionary<PlayerColor, int> CalculateAllAreas(Dictionary<Position, PlayerColor> pixels)
    {
        var areas = new Dictionary<PlayerColor, int>();
        
        foreach (var pixel in pixels.Values)
        {
            if (!areas.ContainsKey(pixel))
                areas[pixel] = 0;
            areas[pixel]++;
        }
        
        return areas;
    }

    public int CalculateAreaChange(Position position, int brushSize, PlayerColor color, Dictionary<Position, PlayerColor> pixels)
    {
        int areaChange = 0;
        var affectedPixels = GetAffectedPixels(position, brushSize);
        
        foreach (var pixelPos in affectedPixels)
        {
            if (!pixelPos.IsWithinBounds(800, 600)) continue;
            
            // 如果像素未被占用或已被当前颜色占用，可以涂色
            if (!pixels.TryGetValue(pixelPos, out var existingColor) || existingColor == color)
            {
                areaChange++;
            }
        }
        
        return areaChange;
    }

    public void UpdateAreaCache(PlayerColor color, int areaChange)
    {
        lock (_cacheLock)
        {
            if (!_areaCache.ContainsKey(color))
                _areaCache[color] = 0;
            _areaCache[color] += areaChange;
        }
    }

    public Dictionary<PlayerColor, int> GetCachedAreas()
    {
        lock (_cacheLock)
        {
            return new Dictionary<PlayerColor, int>(_areaCache);
        }
    }

    public void ClearCache()
    {
        lock (_cacheLock)
        {
            _areaCache.Clear();
        }
    }

    private static IEnumerable<Position> GetAffectedPixels(Position center, int brushSize)
    {
        var pixels = new List<Position>();
        int radius = brushSize / 2;
        
        for (int x = center.X - radius; x <= center.X + radius; x++)
        {
            for (int y = center.Y - radius; y <= center.Y + radius; y++)
            {
                // 圆形画笔（可选：使用距离计算实现真正的圆形）
                if (Math.Pow(x - center.X, 2) + Math.Pow(y - center.Y, 2) <= Math.Pow(radius, 2))
                {
                    pixels.Add(new Position(x, y));
                }
            }
        }
        
        return pixels;
    }
} 